<?php

require_once './application/core/CoreBase.php';
require_once './library/XML/xmlToObjArray.php';
require_once './application/models/Tables/cache.php';
require_once './application/core/Client/visualisationSoap.php';
require_once './application/entity/topologie/imageTopologie.php';
require_once './application/entity/topologie/lancementTopologieResult.php';
require_once './application/models/Tables/Composant.php';
require_once './application/models/Objets/Composant.php';

class TopologieCore extends CoreBase
{

    private $_exedot;
    private $_pathTmp;
    private $_nbNode;

    public function __construct(&$controller)
    {
        parent::__construct($controller);

        $this->_configPath = './application/configuration/config.ini';
        $this->config = new Zend_Config_Ini($this->_configPath, 'topologie');
        $this->_exedot = $this->config->graphviz->location;
        $this->_pathTmp = $this->config->generation->pathTmp;
        $this->_session = new Zend_Session_Namespace('session');
        if (substr($this->_pathTmp, '-1') == "\\")
            $this->_pathTmp = substr_replace($this->_pathTmp, "", "-1");
        if (substr($this->_pathTmp, '-1') != '/')
            $this->_pathTmp .= '\\';
    }

    private function nettoyage()
    {
        if (file_exists($this->_pathTmp . $this->_session->nameMap . ".map"))
            unlink($this->_pathTmp . $this->_session->nameMap . ".map");
        if (file_exists($this->_pathTmp . $this->_session->nameMap . ".gif"))
            unlink($this->_pathTmp . $this->_session->nameMap . ".gif");
        if (file_exists($this->_pathTmp . $this->_session->nameMap . ".dot"))
            unlink($this->_pathTmp . $this->_session->nameMap . ".dot");
    }

    private function DonneComposantsPourMap($idMap)
    {
        $compo = new ObjectComposant();
        $tabCompo = $compo->DonneComposantsPourMap($idMap);

        $tabCompo = $tabCompo[0]['ConfigurationXml'];
        $tabCompo = explode(';', $tabCompo);
        $tabCompteur = array();
        foreach ($tabCompo as $value)
        {
            $liens = explode('=', $value);
            $i = 0;
            $nameComposantOrigineLien = '';
            $ipComposantOrigineLien = '';
            foreach ($liens as $valueLiens)
            {
                $infosComposant = explode(':', $valueLiens);
                if (count($infosComposant) == 4)
                {
                    if ($i == 0)
                    {
                        $nameComposantOrigineLien = explode('{', $infosComposant[0]);
                        if (count($nameComposantOrigineLien) == 2)
                            $nameComposantOrigineLien = $nameComposantOrigineLien[1];
                        else
                            $nameComposantOrigineLien = $nameComposantOrigineLien[0];
                        $infosComposant[3] = explode('\\', $infosComposant[3]);
                        $infosComposant[3] = $infosComposant[3][0];

                        $ipComposantOrigineLien = $infosComposant[1];
                        if (!isset($tabCompteur[$nameComposantOrigineLien]))
                            $tabCompteur[$nameComposantOrigineLien] = 0;
                        else
                            $tabCompteur[$nameComposantOrigineLien]++;
                        $infos[$nameComposantOrigineLien][$ipComposantOrigineLien]['ETHERNET'] = $infosComposant[3];
                        $infos[$nameComposantOrigineLien][$ipComposantOrigineLien]['MAC'] = $infosComposant[2];
                        $infos[$nameComposantOrigineLien][$ipComposantOrigineLien]['INDICE'] = $tabCompteur[$nameComposantOrigineLien];
                    }
                    else
                    {
                        if (!isset($tabCompteur[$infosComposant[0]]))
                            $tabCompteur[$infosComposant[0]] = 0;
                        else
                            $tabCompteur[$infosComposant[0]]++;
                        $infosComposant[3] = explode('\\', $infosComposant[3]);
                        $infosComposant[3] = $infosComposant[3][0];

                        $infos[$infosComposant[0]][$infosComposant[1]]['ETHERNET'] = $infosComposant[3];
                        $infos[$infosComposant[0]][$infosComposant[1]]['MAC'] = $infosComposant[2];
                        $infos[$infosComposant[0]][$infosComposant[1]]['INDICE'] = $tabCompteur[$infosComposant[0]];
                        $infos[$nameComposantOrigineLien][$ipComposantOrigineLien]['LINK'][] = array('NAME' => $infosComposant[0],
                            'IP' => $infosComposant[1]);
                    }
                    $i++;
                }
            }
        }

        foreach ($infos as $key => $value)
            foreach ($value as $key2 => $value2)
                if (!array_key_exists('LINK', $infos[$key][$key2]))
                    $infos[$key][$key2]['LINK'] = array();

        return $infos;
    }

    private function genereDot()
    {
        $infos = $this->DonneComposantsPourMap($this->_session->idMap);
        $composantDb = new TableComposant();
        foreach ($infos as $nameComposant => $infosComposant)
        {
            $composant = $composantDb->getComposantName($nameComposant);
            if (count($composant) == 1)
                $infos[$nameComposant]['ID'] = $composant[0]['IdComposant'];
        }

        $dot = 'digraph callgraph {' . "\n";
        $dot .= 'graph [bgcolor=' . $this->config->diagram->background . ', ratio="1"];' . "\n";
        $dot .= 'node [fontname="' . $this->config->diagram->fontnameNode . '", width="7"];' . "\n";
        $dot .= 'edge [dir="none", color="' . $this->config->diagram->linkColorOk . '"];' . "\n";
        $dot .= 'fontname="' . $this->config->diagram->fontname . '";' . "\n";

        $dotLink = '';
        $dot .= 'subgraph reseau1 {' . "\n";
        $dot .= 'label="";' . "\n"; // Au futur nous pourrons gérer ici des sous réseau avec des sous graph
        $dot .= 'node [shape="none"]' . "\n";

        $i = 0;
        foreach ($infos as $nameComposant => $interfaces)
        {
            if (isset($interfaces['ID']) ||
                    isset($interfaces['INDICE']) ||
                    isset($interfaces['LINK']) ||
                    isset($interfaces['NAME']) ||
                    isset($interfaces['ETHERNET']))
            {
                $dot .= 'node [label="' . $nameComposant . '", labelloc="b", tooltip="' . $nameComposant . '", ratio="fill"; image="' . $this->config->diagram->composant . '"] node_' . $nameComposant . "\n";
                foreach ($interfaces as $ip => $interface)
                {
                    if ($ip == 'ID')
                        break;
                    foreach ($interface['LINK'] as $link)
                        $dotLink .= 'node_' . $nameComposant . ' -> ' . 'node_' . $link['NAME'] . ' [label="        ", labeltooltip=""];' . "\n";
                }
            }
            $i++;
        }
        $dot .= '}' . "\n";
        $dot .= $dotLink . "\n";
        $dot .= '}';
        $f = fopen($this->_pathTmp . $this->_session->nameMap . '.dot', 'w');
        fwrite($f, $dot);
        fclose($f);
        return true;
    }

    private function genereImage()
    {
        $result = new ImageTopologie();
        // Creation de l'image
        $map = $this->_pathTmp . $this->_session->nameMap . '.map';
        $dot = $this->_pathTmp . $this->_session->nameMap . '.dot';
        $svg = $this->_pathTmp . $this->_session->nameMap . '.svg';
        $exec = $this->_exedot . ' -Tsvg -o "' . $svg . '" "' . $dot . '"';
        exec($exec);
        // Recolte des coordonnes pour la map
        $ContenuMap = $this->getFileInBuffer($svg);
        $ContenuMap = str_replace($this->_pathTmp, $this->config->generation->httpImg, $ContenuMap);
        $f = fopen($svg, 'w');
        fwrite($f, $ContenuMap);
        fclose($f);
        $result->nameMap = $this->_session->nameMap;
        $result->img = $this->config->generation->dossierImg . $this->_session->nameMap . '.svg';
        $result->nbNode = $this->_nbNode;
        return $result;
    }

    private function getFileInBuffer($file)
    {
        $f = fopen($file, "r");
        $buffer = '';
        if ($f)
        {
            while (!feof($f))
                $buffer .= fgets($f);
            fclose($f);
        }
        return $buffer;
    }

    // Génére une image de topologie à partir du nom d'une map
    // renvoie le lien vers l'image générée
    private function generation()
    {
        $this->nettoyage();
        if ($this->genereDot())
            return $this->genereImage();
        return null;
    }

    public function Lancement()
    {
        // On génére l'image

        $this->_session->nameMap = $this->_controller->getRequest()->getParam('name');
        $obj = new TableMap();
        $this->_session->idMap = $obj->getMapID($this->_session->nameMap);
        $this->_session->idMap = $this->_session->idMap[0]['IdMap'];
        $this->MiseEnAttenteReponse(false, '/topologie/lancementresp', $this->generation());
    }

    public function ChangementComposantMap()
    {
        $this->_session->nameCompo = $this->_controller->getRequest()->getParam('name');
        $composantDb = new TableComposant();
        $this->_session->nameCompo = str_replace("node_", "", $this->_session->nameCompo);
        $this->_session->nameCompo = str_replace("\n", "", $this->_session->nameCompo);
        $composant = $composantDb->getComposantName($this->_session->nameCompo);
        $this->_session->idComposant = $composant[0]['IdComposant'];
        $this->_session->ipCompo = $composant[0]['Ip'];
        $this->MiseEnAttenteReponse(false, '/topologie/changementcomposantmapresp', NULL);
    }

    public function ChargementDetailsComposantMap()
    {
        $this->_controller->view->id = $this->_session->idComposant;
        $tableComposant = new ObjectComposant();
        $this->_controller->view->infos = $tableComposant->rechercheComposantId($this->_controller->view->id);
    }

    public function ChargementInterfacesComposantMap()
    {
        $this->_controller->view->id = $this->_session->idComposant;
        $this->_controller->view->infos = $this->ChargementInterfacesComposantMapInternal($this->_controller->view->id);
    }

    private function ChargementInterfacesComposantMapInternal($idComposant)
    {
        $tableComposant = new ObjectComposant();
        $interfaces = $tableComposant->rechercheDetailComposant($idComposant);
        $return = array();
        $i = 0;
        foreach ($interfaces as $interface)
        {
            $return[$i] = array();
            foreach ($interface as $key => $value)
            {
                $value = explode('=', $value);
                if (count($value) == 2)
                {
                    $value = $value[1];
                    $value = explode(';', $value);
                    $value = $value[0];
                }
                else
                    $value = $value[0];
                $return[$i][$key] = $value;
            }
            if ($return[$i]['MacInterface'] == '')
                unset($return[$i]);
            $i++;
        }
        return $return;
    }

    public function ChargementActionsComposantMap()
    {
        //
    }

    public function ChargementInterfacesSpecifiquesMap()
    {
        $this->_controller->view->idInterface = $this->_controller->getRequest()->getParam('idInterface');
    }

    public function ChargementTitreComposantMap()
    {
        $this->_controller->view->Compo = $this->_session->nameCompo;
        $this->_controller->view->CompoIP = $this->_session->ipCompo;
        $this->_controller->view->Titre = TOPOLOGI_BODY_DESCRIPTION_COMPOSANT . ' ' . $this->_session->nameCompo;
    }

}
